﻿#region NeoPatterns
// 
// NeoPatterns framework is released under LGPLv3 license.
// See http://www.opensource.org/licenses/lgpl-3.0.html for more details.
// 
// Please visit http://neopatterns.wikidot.com for more information about NeoPatterns
// 
// Copyright (c) Pascal Craponne 2008
// 
#endregion

using System.Collections.Generic;
using NeoPatterns.Core.Registry;
using NeoPatterns.Utility;

namespace NeoPatterns.Patterns.FactoryMethod
{
    public static class ObjectDefinitionTransportExtension
    {
        /// <summary>
        /// Registers an object if IFactoryMethod&lt;TValue,TResultInterface> type, exposing the given objects for given states
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <typeparam name="TResultInterface"></typeparam>
        /// <param name="objectRegistry"></param>
        /// <param name="factoryMethodObjectName"></param>
        /// <param name="factoryDefinitions"></param>
        public static void RegisterFactoryMethod<TValue, TResultInterface>(this IObjectRegistry objectRegistry, string factoryMethodObjectName, params FactoryDefinition<TValue>[] factoryDefinitions)
        {
            objectRegistry.Register<ObjectScopeFactoryMethod<TValue, TResultInterface>>().WithCreator(
                or => new ObjectScopeFactoryMethod<TValue, TResultInterface>(or, factoryDefinitions)
                ).UnderName(factoryMethodObjectName);
        }

        /// <summary>
        /// Registers an object if IFactoryMethod&lt;TValue,TResultInterface> type, exposing the given objects for given states
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <typeparam name="TResultInterface"></typeparam>
        /// <param name="objectRegistry"></param>
        /// <param name="factoryMethodObjectName"></param>
        /// <param name="value0"></param>
        /// <param name="concreteObjectName0"></param>
        /// <param name="otherValues"></param>
        public static void RegisterFactoryMethod<TValue, TResultInterface>(this IObjectRegistry objectRegistry, string factoryMethodObjectName, TValue value0, string concreteObjectName0, params object[] otherValues)
        {
            var factoryDefinitions = new List<FactoryDefinition<TValue>> { new FactoryDefinition<TValue>(value0, concreteObjectName0) };
            for (int paramIndex = 0; paramIndex < otherValues.Length; paramIndex += 2)
            {
                factoryDefinitions.Add(new FactoryDefinition<TValue>((TValue)otherValues[paramIndex],
                                                                     (string)otherValues[paramIndex + 1]));
            }
            RegisterFactoryMethod<TValue, TResultInterface>(objectRegistry, factoryMethodObjectName, factoryDefinitions.ToArray());
        }
    }
}